/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package gew.services;

import gew.data.DataForLoad;
import gew.utils.SqlUtils;
import javax.ejb.EJB;
import javax.ejb.Stateless;

/**
 *
 * @author sukhoruchkinan
 * @see Сервис подготовки запросов загрузки данных из comtrade
 */
@Stateless
public class TradeLoadPreparationService {

    private final static Integer LIMIT_COUNT = 100000;
    private final static Integer LIMIT_PARAM = 5;
    private final static Integer DATA_FOR_LOAD_STATUS_READY = 1;
    private final static Integer DATA_FOR_LOAD_STATUS_EXECUTION = 2;
    private final static Integer DATA_FOR_LOAD_STATUS_EXECUTED = 3;

    private Boolean isOccupied = false;

    /**
     * Сервис выполнения запросов к СУБД
     */
    @EJB
    private QueryService queryService;
    
    private Boolean execute() {
        // Получение первой записи (из таблицы данных к загрузке),
        // в которой Статус = К загрузке (1)
        DataForLoad dataForLoad = queryService.getNextDataForLoad(DATA_FOR_LOAD_STATUS_READY);

        // Если записей к загрузке нет
        if (dataForLoad == null) {
            System.out.println("Nothing to load");
            // И выйти из процедуры
            return false;
        }

        // Иначе нужно обработать полученную строку к загрузке
        // Если предполагаемое количество результатов запроса больше, чем лимит
        if (dataForLoad.getCount() > LIMIT_COUNT) {

            // Получить id строк к загрузке через запятую
            String dataForLoadIds = queryService.getDataForLoadGroupIds(
                    dataForLoad.getReporterId(), dataForLoad.getPeriodId(), dataForLoad.getCommodityGroupTypeId(), DATA_FOR_LOAD_STATUS_READY);
            dataForLoadIds = dataForLoadIds
                    .concat(SqlUtils.COMMA)
                    .concat(dataForLoad.getId().toString());
            System.out.println("dataForLoadIds: " + dataForLoadIds);

            // Пометить все эти записи статусом В обработке (2)
            try {
                // Пометить все эти записи статусом В обработке (2)
                queryService.updateDataForLoadGroupStatus(dataForLoadIds, DATA_FOR_LOAD_STATUS_EXECUTION);

                // Сформировать на основании этих записей запросы и имена файлов
                // для последующей загрузки; и вставить их в таблицу запросов
                queryService.insertDataForLoadGroupToLoadRequests(dataForLoadIds, true);

                // Пометить все эти записи статусом Обработаны (3)
                queryService.updateDataForLoadGroupStatus(dataForLoadIds, DATA_FOR_LOAD_STATUS_EXECUTED);

            } catch (Exception e) {
                System.out.println(e.getMessage());
            } finally {
            }
            return true;
        } else {
            try {
                String id = dataForLoad.getId().toString();
                // Пометить все эти записи статусом В обработке (2)
                queryService.updateDataForLoadGroupStatus(id, DATA_FOR_LOAD_STATUS_EXECUTION);

                // Получить следующие запись к загрузке с тем же репортером,
                // классификацией и статусом
                // (но не одну из уже полученных)
                String notInIds = id;
                Integer currentCount = dataForLoad.getCount();
                DataForLoad nextDataForLoad = null;
                Integer paramCount = 1;
                do {
                    nextDataForLoad = queryService.getNextDataForLoad(
                            DATA_FOR_LOAD_STATUS_READY, dataForLoad.getReporterId(), dataForLoad.getCommodityGroupTypeId(), LIMIT_COUNT - currentCount, notInIds
                    );

                    if (nextDataForLoad != null) {
                        queryService.updateDataForLoadGroupStatus(nextDataForLoad.getId().toString(), DATA_FOR_LOAD_STATUS_EXECUTION);
                        notInIds = notInIds.concat(SqlUtils.COMMA).concat(nextDataForLoad.getId().toString());
                        currentCount = currentCount + nextDataForLoad.getCount();
                        paramCount++;
                    }

                } while (currentCount < LIMIT_COUNT && nextDataForLoad != null && paramCount < LIMIT_PARAM);

                System.out.println("dataForLoadIds: " + notInIds);
                
                // Для выбранных записей (или одной) сформировать запрос и
                // добавить его в таблицу запросов
                queryService.insertDataForLoadGroupToLoadRequests(notInIds, false);

                // Пометить все эти записи статусом Обработаны (3)
                queryService.updateDataForLoadGroupStatus(notInIds, DATA_FOR_LOAD_STATUS_EXECUTED);

            } catch (Exception e) {
                System.out.println(e.getMessage());
            } finally {
            }
            return true;
        }
    }

    public void trytoStart() {
        if (isOccupied) {
            System.out.println("is occupied");
            return;
        }

        // Установка флага исполнения в Истина
        isOccupied = true;

        try {
            while (execute()) {}
        } catch (Exception e){
            System.out.println(e.getMessage());
        } finally {
            isOccupied = false;
        }
    }

}
